package teach.aistar.tasks;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import teach.aistar.service.ISeckillService;

import java.util.List;
import java.util.Map;

/**
 * 本类用来演示: SpringBoot功能 - 定时任务调度器
 *
 * @author: success
 * @date: 2021/5/13 9:15 上午
 */
@Component
public class SeckillTasks {

    @Autowired
    private ISeckillService seckillService;
    
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 定时任务 - 预先加载web_seckill表中参加秒杀活动的商品id到redis中.
     *
     * 该任务每2s执行一次
     */




    @Scheduled(cron = "0/2 * * * * *")
    public void init(){
        //1. 加载出秒杀活动的商品的id - 从mysql中
        List<Map<String,Object>> maps = seckillService.unStartSeckill();

        //2. 判断
        if(null!=maps && maps.size()>0){
            System.out.println("秒杀活动未开始...");
            //3. 遍历这个集合
            for (Map<String, Object> map : maps) {
                //redis存储秒杀的信息
                //key - seckill_product_2   2,2,2,2,2
                //4. 获取秒杀的id
                Long id = (Long) map.get("id");
                int num = (int) map.get("num");

                //有序可重复 - 操作有序可重复列表 - list
                ListOperations list = redisTemplate.opsForList();

                //获取集合列表的长度
                long size = list.size("seckill_product_"+id);

                //目的是为了仅仅加载一次
                if(size==0) {

                    //存储状态 - 操作字符串 - string
                    ValueOperations vop = redisTemplate.opsForValue();
                    vop.set("seckill_product_status_" + id, "0");

                    for (int i = 0; i < num; i++) {
                        list.leftPush("seckill_product_" + id, id);
                    }
                }
            }
        }
    }

    /**
     * 秒杀时间到,但是还没有结束
     * 1. 更新mysql - status => {0}-{1}
     * 2. 更新redis - status => {0}-{1}
     */
    @Scheduled(cron = "0/2 * * * * *")
    public void starting(){
        //1. 尝试加载出秒杀活动进行中的商品的id
        List<Long> ids = seckillService.findKillStarting();

        if(ids!=null && ids.size()>0){
            System.out.println("===秒杀活动进行中===");
            ValueOperations vop = redisTemplate.opsForValue();
            for (Long id : ids) {
                vop.set("seckill_product_status_"+id,"1");
            }
        }

        //2. 更新mysql - status{0}->{1}
        seckillService.updateStarting();
    }

    /**
     * 秒杀活动结束了
     * 1. 更新mysql - status => {1}->{2}
     * 2. 处理redis,删除key为
     *    1) "seckill_product_status_2"
     *    2) "seckill_product_2"
     *
     *    思考-> redis中有哪些key??? -> 秒杀id
     */
    @Scheduled(cron = "0/2 * * * * *")
    public void endKill(){
        //尝试获取活动已经结束之后的商品的id
        List<Long> ids = seckillService.findEndKillId();

        if(null!=ids && ids.size()>0){
            System.out.println("秒杀活动已经结束了...");

            //删除俩个key
            for (Long id : ids) {
                redisTemplate.delete("seckill_product_"+id);
                redisTemplate.delete("seckill_product_status_"+id);
            }
        }

        //更新{1}->{2}
        seckillService.endKill();
    }
}
